/*
 * Copyright 2023-2085 xujin <ceo@itgrail.com>
 *
 * Licensed under the Grail License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://itgrail.com/docs?id=3&catalogId=87
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.itgrail.pilot.app.command.query;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Preconditions;
import com.itgrail.grail.cqrs.annotation.CmdHandler;
import com.itgrail.grail.cqrs.command.CommandExecutorI;
import com.itgrail.grail.dto.PageResult;
import com.itgrail.grail.dto.ResultData;
import com.itgrail.grail.utils.reflect.BeanMapper;
import com.itgrail.pilot.app.command.cmo.query.PageQueryUserCmd;
import com.itgrail.pilot.app.command.co.UserCO;
import com.itgrail.pilot.app.service.DepartmentService;
import com.itgrail.pilot.domain.user.contant.OkrConstants;
import com.itgrail.pilot.infrastructure.tunnel.db.dao.*;
import com.itgrail.pilot.infrastructure.tunnel.db.dataobject.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@CmdHandler
@Slf4j
public class PageQueryUserCmdExe implements CommandExecutorI<ResultData<PageResult<UserCO>>, PageQueryUserCmd> {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserRolesMapper userRolesMapper;

    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private DepartmentService departmentService;

    @Autowired
    private DepartmentUserMapper departmentUserMapper;

    @Override
    public ResultData<PageResult<UserCO>> execute(PageQueryUserCmd pageQueryUserCmd) {
        ResultData<PageResult<UserCO>> resultData = ResultData.success(null);
        if (!check(pageQueryUserCmd, resultData)) {
            return resultData;
        }
        try {
            IPage<UserDO> rolePage = pageGetUser(pageQueryUserCmd);
            PageResult<UserCO> pageResult = new PageResult<>();
            List<UserDO> userDOList = rolePage.getRecords();
            if (null == userDOList || userDOList.size() == 0) {
                return resultData;
            }
            List<UserCO> userCOS = BeanMapper.mapList(userDOList, UserDO.class, UserCO.class);
            for (UserCO userCO : userCOS) {
                UserRolesDO userRolesD = userRolesMapper.queryByUserName(userCO.getAccount());
                if (null != userRolesD) {
                    RoleDO roleDO = roleMapper.queryRoleByKey(userRolesD.getRole());
                    if (null != roleDO) {
                        userCO.setRole(roleDO.getName());
                        userCO.setRoleCode(roleDO.getKey());
                    }
                }
                List<DepartmentUserDO> userDeptList = departmentUserMapper.queryByUserId(userCO.getId());
                if(CollUtil.isNotEmpty(userDeptList)){
                    DepartmentDO departmentDO = departmentMapper.selectById(userDeptList.get(0).getDepartmentId());
                    if (departmentDO != null) {
                        if (StrUtil.isNotBlank(departmentDO.getDisplayPath())) {
                            userCO.setDeptName(departmentDO.getDisplayPath());
                        } else {
                            userCO.setDeptName(departmentService.getFullDeptPath(departmentDO.getId()));
                        }
                    }
                }
            }
            pageResult.setList(userCOS);
            pageResult.setCurrentPage(rolePage.getCurrent());
            pageResult.setTotalCount(rolePage.getTotal());
            pageResult.setTotalPage(rolePage.getPages());
            resultData.setData(pageResult);
        } catch (Exception ex) {
            log.warn(String.format("page query app failed, cmd=%s", pageQueryUserCmd), ex);
            resultData.setCode(500);
            resultData.setMsgContent("失败");
        }
        return resultData;
    }

    protected IPage<UserDO> pageGetUser(PageQueryUserCmd cmd) {
        Page<UserDO> page = new Page<>(cmd.getPageNo(), cmd.getPageSize());
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deleted", OkrConstants.NOT_DELETED);
        if (StringUtils.isNoneBlank(cmd.getSearchKey())) {
            queryWrapper.and(qw -> qw
                    .like("name", cmd.getSearchKey()).or()
                    .like("account", cmd.getSearchKey()));
        }
        queryWrapper.orderByAsc("id");
        return userMapper.selectPage(page, queryWrapper);
    }

    protected boolean check(PageQueryUserCmd cmd, ResultData<PageResult<UserCO>> resultData) {
        try {
            Preconditions.checkNotNull(cmd, "cmd不能为null");
            Preconditions.checkNotNull(cmd.getPageNo(), "pageNo不能为null");
            Preconditions.checkNotNull(cmd.getPageSize(), "pageSize不能为null");
            Preconditions.checkArgument(cmd.getPageNo() >= 1, "pageNo不能小于1");
            Preconditions.checkArgument(cmd.getPageSize() >= 1, "pageSize不能小于1");
            Preconditions.checkArgument(cmd.getPageSize() <= 500, "pageSize不能大于500");
        } catch (Exception ex) {
            resultData.setMsgContent(ex.getMessage());
            return false;
        }
        return true;
    }
}
